<!DOCTYPE html>
<html>
<!--
Copyright 2009 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<head>
  <title>Google Earth API Samples - Smooth Animation with frameend</title>
  <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
  <!-- You should probably remove most of this extra cruft if you're copying
       this sample! -->
  <style type="text/css">@import "static/examples.css";</style>
  <style type="text/css">@import "static/prettify/prettify.css";</style>
  <script type="text/javascript" src="static/prettify/prettify.js"></script>
  
  <!-- Change the key below to your own Maps API key -->
  <script type="text/javascript" src="http://www.google.com/jsapi?hl=en&amp;key=ABQIAAAAwbkbZLyhsmTCWXbTcjbgbRSzHs7K5SvaUdm8ua-Xxy_-2dYwMxQMhnagaawTo7L1FE1-amhuQxIlXw"></script>
  <script type="text/javascript">
  /* <![CDATA[ */
  var ge;
  var animRunning = false;
  var ANIM_ALTITUDE = 100;
  
  google.load("earth", "1");

  function init() {
    google.earth.createInstance('map3d', initCB, failureCB);
  }
  
  function initCB(instance) {
    ge = instance;
    ge.getWindow().setVisibility(true);
    
    // add some layers
    ge.getLayerRoot().enableLayerById(ge.LAYER_BORDERS, true);
    ge.getLayerRoot().enableLayerById(ge.LAYER_ROADS, true);

    ge.getOptions().setMouseNavigationEnabled(false);
    
    var camera = ge.createCamera('');
    camera.set(37, -122, ANIM_ALTITUDE, ge.ALTITUDE_RELATIVE_TO_GROUND,
        0, 80, 0);
    ge.getView().setAbstractView(camera);
    
    document.getElementById('installed-plugin-version').innerHTML =
      ge.getPluginVersion().toString();
  }
  
  function failureCB(errorCode) {
  }
  
  function startAnimation() {
    if (!animRunning) {
      ge.getOptions().setFlyToSpeed(ge.SPEED_TELEPORT);
      animRunning = true;
      google.earth.addEventListener(ge, 'frameend', tickAnimation);
      
      // start it off
      tickAnimation();
    }
  }
  
  function stopAnimation() {
    if (animRunning) {
      google.earth.removeEventListener(ge, 'frameend', tickAnimation);
      animRunning = false;
    }
  }
  
  function tickAnimation() {
    // an example of some camera manipulation that's possible w/ the Earth API
    var camera = ge.getView().copyAsCamera(ge.ALTITUDE_RELATIVE_TO_GROUND);
    var dest = destination(camera.getLatitude(), camera.getLongitude(), 10,
                           camera.getHeading());
  
    camera.setAltitude(ANIM_ALTITUDE);
    camera.setLatitude(dest[0]);
    camera.setLongitude(dest[1]);
  
    ge.getView().setAbstractView(camera);
  }
  
  /* Helper functions, courtesy of
     http://www.movable-type.co.uk/scripts/latlong.html */
  function distance(lat1, lng1, lat2, lng2) {
    var a = Math.sin(lat1 * Math.PI / 180) * Math.sin(lat2 * Math.PI / 180);
    var b = Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
        Math.cos((lng2 - lng1) * Math.PI / 180);
    return 6371000 * Math.acos(a + b);
  }
  
  function destination(lat, lng, dist, heading) {
    lat *= Math.PI / 180;
    lng *= Math.PI / 180;
    heading *= Math.PI / 180;
    dist /= 6371000; // angular dist
    
    var lat2 = Math.asin(Math.sin(lat) * Math.cos(dist) + 
                         Math.cos(lat) * Math.sin(dist) * Math.cos(heading));
  
    return [
        180 / Math.PI * lat2,
        180 / Math.PI *
          (lng + Math.atan2(Math.sin(heading) * Math.sin(dist) * Math.cos(lat2),
                            Math.cos(dist) - Math.sin(lat) * Math.sin(lat2)))];
  }
  
  /* ]]> */
  </script>
</head>
<body onload="if(window.prettyPrint)prettyPrint();init();">
  <h1>Google Earth API Samples - Smooth Animation with frameend</h1>
  <dl>
            <dt>Last Modified:</dt><dd>06/08/2009</dd>
    <dt>Installed Plugin Version:</dt><dd id="installed-plugin-version">...</dd>
  </dl>
  <div style="clear: both;"></div>
  
  <div id="ui" style="position: relative;">
    <div id="map3d" style="border: 1px solid silver; width: 500px; height: 500px;"></div>

    <div id="extra-ui" style="position: absolute; left: 520px; top: 0;">
      <input type="button" onclick="startAnimation()" value="Start Animation!"/><br/>
      <input type="button" onclick="stopAnimation()" value="Stop Animation!"/>
      
      <h2>Relevant Resources:</h2>
      <ul>
<li><a href="http://code.google.com/apis/earth/documentation/reference/google_earth_namespace.html">google.earth Namespace Reference</a></li>
<li><a href="http://code.google.com/apis/earth/documentation/reference/interface_g_e_plugin.html">GEPlugin Reference</a></li>
<li><a href="http://www.movable-type.co.uk/scripts/latlong.html">Geo Math Functions (movable-type.co.uk)</a></li>
<a id="playground-button" href="http://code.google.com/apis/ajax/playground/?exp=earth#smooth_animation_with_frameend"><img src="static/playground-button.png"/></a>      </ul>
      <h2>Relevant Code Excerpt:</h2>      <pre class="prettyprint lang-js">var animRunning = false;
var ANIM_ALTITUDE = 100;</pre>      <pre class="prettyprint lang-js">function startAnimation() {
  if (!animRunning) {
    ge.getOptions().setFlyToSpeed(ge.SPEED_TELEPORT);
    animRunning = true;
    google.earth.addEventListener(ge, 'frameend', tickAnimation);
    
    // start it off
    tickAnimation();
  }
}

function stopAnimation() {
  if (animRunning) {
    google.earth.removeEventListener(ge, 'frameend', tickAnimation);
    animRunning = false;
  }
}

function tickAnimation() {
  // an example of some camera manipulation that's possible w/ the Earth API
  var camera = ge.getView().copyAsCamera(ge.ALTITUDE_RELATIVE_TO_GROUND);
  var dest = destination(camera.getLatitude(), camera.getLongitude(), 10,
                         camera.getHeading());

  camera.setAltitude(ANIM_ALTITUDE);
  camera.setLatitude(dest[0]);
  camera.setLongitude(dest[1]);

  ge.getView().setAbstractView(camera);
}

/* Helper functions, courtesy of
   http://www.movable-type.co.uk/scripts/latlong.html */
function distance(lat1, lng1, lat2, lng2) {
  var a = Math.sin(lat1 * Math.PI / 180) * Math.sin(lat2 * Math.PI / 180);
  var b = Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
      Math.cos((lng2 - lng1) * Math.PI / 180);
  return 6371000 * Math.acos(a + b);
}

function destination(lat, lng, dist, heading) {
  lat *= Math.PI / 180;
  lng *= Math.PI / 180;
  heading *= Math.PI / 180;
  dist /= 6371000; // angular dist
  
  var lat2 = Math.asin(Math.sin(lat) * Math.cos(dist) + 
                       Math.cos(lat) * Math.sin(dist) * Math.cos(heading));

  return [
      180 / Math.PI * lat2,
      180 / Math.PI *
        (lng + Math.atan2(Math.sin(heading) * Math.sin(dist) * Math.cos(lat2),
                          Math.cos(dist) - Math.sin(lat) * Math.sin(lat2)))];
}</pre>    </div>
  </div>
</body>
</html>
